package com.njtoyo.taxi.admin.service.platform.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njtoyo.taxi.admin.library.common.OperationRecordHelper;
import com.njtoyo.taxi.admin.library.common.SensitiveOperationHelper;
import com.njtoyo.taxi.admin.library.mail.AuthorizationCodeMailRequest;
import com.njtoyo.taxi.admin.library.mail.SpringMailSender;
import com.njtoyo.taxi.admin.mapper.secondary.entity.SystemSensitiveOperation;
import com.njtoyo.taxi.admin.mapper.secondary.enums.SystemSensitiveOperationObjectType;
import com.njtoyo.taxi.admin.mapper.secondary.enums.SystemSensitiveOperationVerifyMethod;
import com.njtoyo.taxi.admin.mapper.secondary.enums.SystemSensitiveOperationVerifyMode;
import com.njtoyo.taxi.admin.mapper.secondary.mapper.SystemSensitiveOperationMapper;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.sensitive.SensitiveOperationPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.platform.sensitive.SensitiveOperationWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.platform.sensitive.SensitiveRegisteredWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.platform.sensitive.SensitiveUpdateWrapper;
import com.njtoyo.taxi.admin.service.platform.SensitiveOperationService;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import com.njtoyo.taxi.entity.backend.AdminUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.mail.MessagingException;
import java.util.Date;
import java.util.Objects;

@Service
@Slf4j
public class SensitiveOperationServiceImpl implements SensitiveOperationService {

    @Autowired
    private SystemSensitiveOperationMapper systemSensitiveOperationMapper;

    @Autowired
    private SensitiveOperationHelper sensitiveOperationHelper;

    @Autowired
    private SpringMailSender springMailSender;

    @Autowired
    private OperationRecordHelper operationRecordHelper;

    @Override
    public RestResult sendAuthorizationCode(AdminUser adminUser, String operationName) throws MessagingException {
        QueryWrapper<SystemSensitiveOperation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("operation_name", operationName);
        SystemSensitiveOperation operation = systemSensitiveOperationMapper.selectOne(queryWrapper);
        if (Objects.isNull(operation)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        SensitiveOperationHelper helper = sensitiveOperationHelper.init(adminUser, operationName);
        if (!helper.isNeedVerify()) {
            return RestResult.build(ResultEnum.DONT_AUTHORIZATION);
        }
        AdminUser verifyUser = helper.getVerifyUser();
        if (Objects.isNull(verifyUser)) {
            return RestResult.failed("未找到授权人信息，请联系管理员");
        }
        if (Objects.isNull(verifyUser.getEmail())) {
            return RestResult.failed("授权人邮箱未填写，请联系管理员");
        }
        String code = helper.generateCode();
        log.info("生成授权码为: {}", code);
        if (!helper.saveCode(code)) {
            return RestResult.failed("处理失败，请稍后重试");
        }
        // 发邮件
        AuthorizationCodeMailRequest codeRequest = new AuthorizationCodeMailRequest()
                .setMailTo(verifyUser.getEmail())
                .setSensitiveOperationHelper(helper)
                .setCode(code)
                .setExpireDate(helper.getExpireDate());
        springMailSender.sendAuthorizationCodeMail(codeRequest);

        return RestResult.success();
    }

    /**
     * 敏感操作列表
     *
     * @param adminUser
     * @param wrapper
     * @return
     */
    @Override
    public RestResult<Page<SensitiveOperationPresenter>> sensitiveOperationList(AdminUser adminUser, SensitiveOperationWrapper wrapper) {
        Page<SensitiveOperationPresenter> sensitiveOperationPresenterPage =
                systemSensitiveOperationMapper.sensitiveOperationList(wrapper);
        return RestResult.success(sensitiveOperationPresenterPage);
    }

    /**
     * 注册敏感操作
     *
     * @param wrapper
     * @return
     */
    @Override
    public RestResult registered(SensitiveRegisteredWrapper wrapper) {
        String operationName = wrapper.getOperationName();
        String operationDesc = wrapper.getOperationDesc();
        String routeAction = wrapper.getRouteAction();
        Integer count = systemSensitiveOperationMapper.selectOperationName(operationName);
        if (count > 0) {
            return RestResult.failed("已经存在相同的操作标识");
        }
        SystemSensitiveOperation systemSensitiveOperation = new SystemSensitiveOperation();
        systemSensitiveOperation.setRouteAction(routeAction);
        systemSensitiveOperation.setOperationDesc(operationDesc);
        systemSensitiveOperation.setOperationName(operationName);
        systemSensitiveOperationMapper.insert(systemSensitiveOperation);
        operationRecordHelper.addBusinessLog(String.format("注册了敏感操作标识名 [%s] 的的信息",
                wrapper.getOperationName()));
        return RestResult.success();
    }


    /**
     * 修改敏感操作
     *
     * @param wrapper
     * @return
     */
    @Override
    public RestResult update(Long id, SensitiveUpdateWrapper wrapper) {
        SystemSensitiveOperation systemSensitiveOperation = systemSensitiveOperationMapper.selectById(id);
        if (ObjectUtils.isEmpty(systemSensitiveOperation)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        SystemSensitiveOperationVerifyMode verifyMode = wrapper.getVerifyMode();
        SystemSensitiveOperationObjectType verifyObjectType = wrapper.getVerifyObjectType();
        SystemSensitiveOperationVerifyMethod verifyMethod = wrapper.getVerifyMethod();
        if (verifyMode == null && verifyObjectType == null && verifyMethod == null) {
            new LambdaUpdateChainWrapper<>(systemSensitiveOperationMapper)
                    .eq(SystemSensitiveOperation::getId, id)
                    .set(SystemSensitiveOperation::getIsVerifyOpen, wrapper.getIsVerifyOpen())
                    .set(SystemSensitiveOperation::getUpdatedAt, new Date())
                    .update();
            return RestResult.success();
        }
        if (SystemSensitiveOperationObjectType.self.equals(verifyObjectType)) {
            //单步校验 密码验证
            if (SystemSensitiveOperationVerifyMode.one_step.equals(verifyMode)) {
                if (!SystemSensitiveOperationVerifyMethod.login_password.equals(verifyMethod)) {
                    return RestResult.failed("自身 单步校验只能密码验证");
                }
            }
        } else {
            if (SystemSensitiveOperationVerifyMode.one_step.equals(verifyMode)) {
                return RestResult.failed("非自身 不能单步校验");
            }
            if (!SystemSensitiveOperationVerifyMethod.email_code.equals(verifyMethod)) {
                return RestResult.failed("非自身 只能邮箱验证");
            }
        }
        String ignoreAdmin = JSON.toJSONString(wrapper.getIgnoreAdmin());
        new LambdaUpdateChainWrapper<>(systemSensitiveOperationMapper)
                .eq(SystemSensitiveOperation::getId, id)
                .set(SystemSensitiveOperation::getVerifyObjectType, verifyObjectType)
                .set(SystemSensitiveOperation::getAssignedVerifyObjectId, wrapper.getAssignedVerifyObjectId())
                .set(SystemSensitiveOperation::getVerifyMode, verifyMode)
                .set(SystemSensitiveOperation::getVerifyMethod, verifyMethod)
                .set(SystemSensitiveOperation::getIsVerifyOpen, wrapper.getIsVerifyOpen())
                .set(SystemSensitiveOperation::getIgnoreAdmin, ignoreAdmin)
                .set(SystemSensitiveOperation::getUpdatedAt, new Date())
                .update();
        operationRecordHelper.addBusinessLog(String.format("修改了修改敏感操作 [%d] 的的信息", id));
        return RestResult.success();
    }

    /**
     * 删除敏感操作
     *
     * @param id
     * @return
     */
    @Override
    public RestResult delete(Long id) {
        SystemSensitiveOperation systemSensitiveOperation = systemSensitiveOperationMapper.selectById(id);
        if (ObjectUtils.isEmpty(systemSensitiveOperation)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        QueryWrapper<SystemSensitiveOperation> Wrapper
                = new QueryWrapper<>();
        Wrapper.eq("id", id);
        systemSensitiveOperationMapper.delete(Wrapper);
        operationRecordHelper.addBusinessLog(String.format("删除了敏感操作 [%d] 的的信息", id));
        return RestResult.success();
    }
}
